package com.alan.shiro.api.realm;

import com.alan.shiro.api.bean.Permission;
import com.alan.shiro.api.bean.Role;
import com.alan.shiro.api.bean.User;
import com.alan.shiro.api.service.UserService;
import com.alan.shiro.api.token.StatelessToken;
import com.alan.shiro.api.token.manager.TokenManager;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.List;

/**
 * @Auther: Alan liu
 * @Date: 2018/12/13 10:36
 * @Description: 无状态域
 */
@Slf4j
public class StatelessRealm extends AuthorizingRealm {

    @Setter
    @Getter
    private TokenManager tokenManager;

    @Setter
    @Getter
    private UserService userService;


    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof StatelessToken;
    }

    /**
     * 用户认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        log.info("用户认证--doGetAuthenticationInfo");
        StatelessToken statelessToken = (StatelessToken)token;

        Long userId = (Long)statelessToken.getPrincipal();

        checkUserExists(userId);

        String credentials = (String)statelessToken.getCredentials();
        boolean checkToken = tokenManager.checkToken(statelessToken);
        if (checkToken) {
            return new SimpleAuthenticationInfo(userId, credentials, super.getName());
        }else{
            throw new AuthenticationException("token认证失败");
        }
    }

    /**
     * 获取角色与权限信息
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("获取角色与权限信息--doGetAuthorizationInfo");
        //根据用户名查找角色，请根据需求实现
        Long userId = (Long) principals.getPrimaryPrincipal();
        //查询用户
        User user = userService.findByUserId(userId);
        //添加角色和权限
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        for (Role role:user.getRoles()) {
            //添加角色
            info.addRole(role.getRoleName());
            for (Permission permission:role.getPermissions()) {
                //添加权限
                info.addStringPermission(permission.getPermission());
            }
        }
        return info;
    }

    private void checkUserExists(Long userId) throws AuthenticationException {
        Object principal = userService.select(userId);
        if(principal == null){
            throw new UnknownAccountException("userId: "+userId+" wasn't in the system");
        }
    }



}
